package com.durian.base.utils;

import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleObserver;
import androidx.lifecycle.OnLifecycleEvent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
import android.net.NetworkRequest;
import android.os.Build;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import android.telephony.TelephonyManager;

import com.durian.BaseApp;
import com.durian.base.frame.activity.ActivityFrame;


/**
 * 说明：网络工具类
 * <p/>
 * 作者：fanly
 * <p/>
 * 时间：2016/4/5 15:06
 * <p/>
 * 版本：version 1.0
 */
public final class NetUtils {

    protected interface INetCallBack extends LifecycleObserver {
        void setOnNetWorkChangedListener(OnNetWorkChangedListener listener);
    }

    public static class NetCallBack19 extends BroadcastReceiver implements INetCallBack {

        protected ConnectivityManager      mConnectivityManager;
        private   OnNetWorkChangedListener mListener;
        private   ActivityFrame            mActivityFrame;

        public NetCallBack19(ActivityFrame activityFrame) {
            mActivityFrame = activityFrame;
            mConnectivityManager = ((ConnectivityManager) activityFrame.getSystemService(Context.CONNECTIVITY_SERVICE));
        }

        @Override
        public void onReceive(Context context, Intent intent) {
            if (mListener == null) {
                return;
            }
            if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) {
                if (isNetConnected()) {
                    mListener.onAvailable(getNetWorkType());
                } else {
                    mListener.onLost();
                }
            }
        }

        @Override
        public void setOnNetWorkChangedListener(OnNetWorkChangedListener listener) {
            mListener = listener;
        }

        @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
        public void startMonitoring() {
            if (ToolUtils.isNotFinish(mActivityFrame)) {
                IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
                mActivityFrame.registerReceiver(this, filter);
            }
        }

        @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
        public void stopMonitoring() {
            if (mActivityFrame != null) {
                mActivityFrame.unregisterReceiver(this);
            }
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    protected static class NetCallBack21 implements INetCallBack {

        private ConnectivityManager                 mConnectivityManager;
        private NetworkRequest                      mNetworkRequest;
        private OnNetWorkChangedListener            mListener;
        private ConnectivityManager.NetworkCallback mNetworkCallback;

        public NetCallBack21() {
            mConnectivityManager = ((ConnectivityManager) BaseApp.getApp().getSystemService(Context.CONNECTIVITY_SERVICE));
            mNetworkRequest = new NetworkRequest.Builder().addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET).build();
            mNetworkCallback = new ConnectivityManager.NetworkCallback() {
                @Override
                public void onLost(@NonNull Network network) {
                    super.onLost(network);
                    if (mListener != null) {
                        mListener.onLost();
                    }
                }

                @Override
                public void onLosing(@NonNull Network network, int maxMsToLive) {
                    super.onLosing(network, maxMsToLive);
                }

                @Override
                public void onUnavailable() {
                    super.onUnavailable();
                }

                @Override
                public void onAvailable(@NonNull Network network) {
                    super.onAvailable(network);
                    if (mListener != null) {
                        mListener.onAvailable(getNetWorkType());
                    }
                }
            };
        }


        @Override
        public void setOnNetWorkChangedListener(OnNetWorkChangedListener listener) {
            mListener = listener;
        }

        @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
        public void startMonitoring() {
            if (mConnectivityManager != null && mNetworkRequest != null && mNetworkCallback != null) {
                mConnectivityManager.registerNetworkCallback(mNetworkRequest, mNetworkCallback);
            }
        }

        @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
        public void stopMonitoring() {
            if (mConnectivityManager != null && mNetworkCallback != null) {
                mConnectivityManager.unregisterNetworkCallback(mNetworkCallback);
            }
        }

    }

    public interface OnNetWorkChangedListener {
        void onLost();

        void onAvailable(NetWorkType type);
    }

    /******************************* 网络类型 ****************************************/

    // 网络类型
    public enum NetWorkType {
        NETTYPE_NONET, NETTYPE_WIFI, NETTYPE_2G, NETTYPE_3G, NETTYPE_4G
    }

    private NetUtils() {
    }

    /**
     * 说明：获取手机网络状态是否可用
     *
     * @return 返回网络状态【true:网络联通】【false:网络断开】
     */
    public static boolean isNetConnected() {
        try {
            ConnectivityManager connectivityManager = (ConnectivityManager) BaseApp.getApp().getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo network = connectivityManager.getActiveNetworkInfo();
            if (connectivityManager != null) {
                if (network != null && network.isConnected()) {
                    if (network.getState() == NetworkInfo.State.CONNECTED) {
                        return true;
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 说明：获取当前网络类型
     * 字段常量[NetWorkType.NETTYPE_WIFI]
     *
     * @return 0：没有网络 1：WIFI网络 2：2G网络 3：3G网络 4:4G网络
     * int NETTYPE_NONET = 0;
     * int NETTYPE_WIFI = 1;
     * int NETTYPE_2G = 2;
     * int NETTYPE_3G = 3;
     * int NETTYPE_4G = 4;
     */
    public static NetWorkType getNetWorkType() {
        NetWorkType strNetworkType = NetWorkType.NETTYPE_NONET;
        NetworkInfo networkInfo = ((ConnectivityManager) BaseApp.getApp().getSystemService(Context.CONNECTIVITY_SERVICE)).getActiveNetworkInfo();
        if (networkInfo != null && networkInfo.isConnected()) {
            if (networkInfo.getType() == ConnectivityManager.TYPE_WIFI) {
                strNetworkType = NetWorkType.NETTYPE_WIFI;
            } else if (networkInfo.getType() == ConnectivityManager.TYPE_MOBILE) {
                String _strSubTypeName = networkInfo.getSubtypeName();
                int networkType = networkInfo.getSubtype();
                switch (networkType) {
                    case TelephonyManager.NETWORK_TYPE_GPRS:
                    case TelephonyManager.NETWORK_TYPE_EDGE:
                    case TelephonyManager.NETWORK_TYPE_CDMA:
                    case TelephonyManager.NETWORK_TYPE_1xRTT:
                    case TelephonyManager.NETWORK_TYPE_IDEN:
                        strNetworkType = NetWorkType.NETTYPE_2G;
                        break;
                    case TelephonyManager.NETWORK_TYPE_UMTS:
                    case TelephonyManager.NETWORK_TYPE_EVDO_0:
                    case TelephonyManager.NETWORK_TYPE_EVDO_A:
                    case TelephonyManager.NETWORK_TYPE_HSDPA:
                    case TelephonyManager.NETWORK_TYPE_HSUPA:
                    case TelephonyManager.NETWORK_TYPE_HSPA:
                    case TelephonyManager.NETWORK_TYPE_EVDO_B:
                    case TelephonyManager.NETWORK_TYPE_EHRPD:
                    case TelephonyManager.NETWORK_TYPE_HSPAP:
                        strNetworkType = NetWorkType.NETTYPE_3G;
                        break;
                    case TelephonyManager.NETWORK_TYPE_LTE:
                        strNetworkType = NetWorkType.NETTYPE_4G;
                        break;
                    default:
                        if (_strSubTypeName.equalsIgnoreCase("TD-SCDMA") || _strSubTypeName.equalsIgnoreCase("WCDMA") || _strSubTypeName.equalsIgnoreCase("CDMA2000")) {
                            strNetworkType = NetWorkType.NETTYPE_3G;
                        } else {
                            strNetworkType = NetWorkType.NETTYPE_NONET;
                        }
                        break;
                }
            }
        }
        return strNetworkType;
    }

    /**
     * 说明：判断当前网络是否是wifi
     *
     * @return
     */
    public static boolean isWifi() {
        return getNetWorkType() == NetWorkType.NETTYPE_WIFI;
    }

    /**
     * 说明：判断当前网络是否是2G
     *
     * @return
     */
    public static boolean is2G() {
        return getNetWorkType() == NetWorkType.NETTYPE_2G;
    }

    /**
     * 说明：判断当前网络是否是3G
     *
     * @return
     */
    public static boolean is3G() {
        return getNetWorkType() == NetWorkType.NETTYPE_3G;
    }

    /**
     * 说明：判断当前网络是否是4G
     *
     * @return
     */
    public static boolean is4G() {
        return getNetWorkType() == NetWorkType.NETTYPE_4G;
    }

    /**
     * 说明：判断当前网络是否是3G或是4G
     *
     * @return
     */
    public static boolean is3Gor4G() {
        return is3G() || is4G();
    }


    /**
     * 说明：注册网络监听
     *
     * @param listener
     */
    public static void registerNetworkChangedCallBack(ActivityFrame activityFrame, OnNetWorkChangedListener listener) {
        INetCallBack callBack = null;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            callBack = new NetCallBack21();
        } else {
            callBack = new NetCallBack19(activityFrame);
        }
        callBack.setOnNetWorkChangedListener(listener);
        activityFrame.getLifecycle().addObserver(callBack);
    }

}
